#include "GY_AttributesGroup.h"
#include "GY_GraphicsWideTextItem.h"

GY_AttributesGroup::GY_AttributesGroup(const QString &guid, QGraphicsItem *parent) : GY_ContainerTransform(guid,this, parent)
{
    initializationPropertyInfo();
    this->setCenterPointF(m_PropertyInfoMap["Position"].propertyValue.toPointF());
}

void GY_AttributesGroup::initializationPropertyInfo()
{
    GY_PropertyInfo ObjectName(this);
    ObjectName.propertyName = "ObjectName";
    ObjectName.propertyValue = QString();
    ObjectName.updateType = Update|OrdinaryAttributes;
    ObjectName.propertyType = QStringPropertyType;
    ObjectName.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updateObjectName;
    m_PropertyInfoMap.insert("ObjectName",ObjectName);
    m_PropertyInfoMap[ObjectName.propertyName].setConnect();

    //位置
    GY_PropertyInfo positonPropertyInfo(this);
    positonPropertyInfo.propertyName="Position";
    positonPropertyInfo.propertyValue=QPointF(0,0);
    positonPropertyInfo.updateType = Update|MoveUpdate|PointOfRelative;
    positonPropertyInfo.propertyType = PointPropertyType;
    positonPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updatePosition;
    m_PropertyInfoMap.insert(positonPropertyInfo.propertyName,positonPropertyInfo);
    m_PropertyInfoMap[positonPropertyInfo.propertyName].setConnect();

    //Fill属性来源Local，Inherit
    GY_PropertyInfo fillAttributesPropertyInfo(this);
    fillAttributesPropertyInfo.propertyName="FillAttributes";
    fillAttributesPropertyInfo.propertyValue=false;
    fillAttributesPropertyInfo.updateType = Update|OrdinaryAttributes;
    fillAttributesPropertyInfo.propertyType = BoolPropertyType;
    fillAttributesPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updateFillAttributes;
    m_PropertyInfoMap.insert(fillAttributesPropertyInfo.propertyName,fillAttributesPropertyInfo);
    m_PropertyInfoMap[fillAttributesPropertyInfo.propertyName].setConnect();

    //填充样式
    GY_PropertyInfo fillStylePropertyInfo(this);
    fillStylePropertyInfo.propertyName="FillStyle";
    fillStylePropertyInfo.propertyValue=true;
    fillStylePropertyInfo.updateType = Update|OrdinaryAttributes;
    fillStylePropertyInfo.propertyType = BoolPropertyType;
    fillStylePropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updateFillStyle;
    m_PropertyInfoMap.insert(fillStylePropertyInfo.propertyName,fillStylePropertyInfo);
    m_PropertyInfoMap[fillStylePropertyInfo.propertyName].setConnect();

    //填充颜色
    GY_PropertyInfo fillColorPropertyInfo(this);
    fillColorPropertyInfo.propertyName="FillColor";
    fillColorPropertyInfo.propertyValue=QColor(255,255,255);
    fillColorPropertyInfo.updateType = Update|OrdinaryAttributes;
    fillColorPropertyInfo.propertyType = ColorPropertyType;
    fillColorPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updateFillColor;
    m_PropertyInfoMap.insert(fillColorPropertyInfo.propertyName,fillColorPropertyInfo);
    m_PropertyInfoMap[fillColorPropertyInfo.propertyName].setConnect();

    //填充渐变色
    GY_PropertyInfo FillGradient(this);
    FillGradient.propertyName = "FillGradient";
    FillGradient.propertyValue = QVariant();
    FillGradient.updateType = Update|OrdinaryAttributes;
    FillGradient.propertyType = FillGradientPropertyType;
    FillGradient.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updateFillGradient;
    m_PropertyInfoMap.insert("FillGradient",FillGradient);
    m_PropertyInfoMap[FillGradient.propertyName].setConnect();

    //Pattern填充图案数据
    GY_PropertyInfo Pattern(this);
    Pattern.propertyName = "Pattern";
    Pattern.propertyValue = QVariant();
    Pattern.propertyType = PatternPropertyType;
    Pattern.updateType = Update|OrdinaryAttributes;
    Pattern.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updatePattern;
    m_PropertyInfoMap.insert("Pattern",Pattern);
    m_PropertyInfoMap[Pattern.propertyName].setConnect();

    //填充透明度
    GY_PropertyInfo FillOpacity(this);
    FillOpacity.propertyName = "FillOpacity";
    FillOpacity.propertyValue = 1;
    FillOpacity.updateType = Update|OrdinaryAttributes;
    FillOpacity.propertyType = QrealPropertyType;
    FillOpacity.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updateFillOpacity;
    m_PropertyInfoMap.insert("FillOpacity",FillOpacity);
    m_PropertyInfoMap[FillOpacity.propertyName].setConnect();

    //Pen属性来源Local，Inherit
    GY_PropertyInfo penAttributesPropertyInfo(this);
    penAttributesPropertyInfo.propertyName="PenAttributes";
    penAttributesPropertyInfo.propertyValue=false;
    penAttributesPropertyInfo.updateType = Update|OrdinaryAttributes;
    penAttributesPropertyInfo.propertyType = BoolPropertyType;
    penAttributesPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updatePenAttributes;
    m_PropertyInfoMap.insert(penAttributesPropertyInfo.propertyName,penAttributesPropertyInfo);
    m_PropertyInfoMap[penAttributesPropertyInfo.propertyName].setConnect();

    //笔颜色
    GY_PropertyInfo PenColor(this);
    PenColor.propertyName = "PenColor";
    PenColor.propertyValue = QColor(255,255,255);
    PenColor.updateType = Update|OrdinaryAttributes;
    PenColor.propertyType = ColorPropertyType;
    PenColor.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updatePenColor;
    m_PropertyInfoMap.insert("PenColor",PenColor);
    m_PropertyInfoMap[PenColor.propertyName].setConnect();

    //线条样式
    GY_PropertyInfo LineStyle(this);
    LineStyle.propertyName = "LineStyle";
    LineStyle.propertyValue = QVariant();
    LineStyle.updateType = Update|OrdinaryAttributes;
    LineStyle.propertyType = LineStylePropertyType;
    LineStyle.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updateLineStyle;
    m_PropertyInfoMap.insert("LineStyle",LineStyle);
    m_PropertyInfoMap[LineStyle.propertyName].setConnect();

    //笔透明度
    GY_PropertyInfo PenOpacity(this);
    PenOpacity.propertyName = "PenOpacity";
    PenOpacity.propertyValue = 1;
    PenOpacity.updateType = Update|OrdinaryAttributes;
    PenOpacity.propertyType = QrealPropertyType;
    PenOpacity.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updatePenOpacity;
    m_PropertyInfoMap.insert("PenOpacity",PenOpacity);
    m_PropertyInfoMap[PenOpacity.propertyName].setConnect();

    //未知属性
    GY_PropertyInfo LineWidth(this);
    LineWidth.propertyName = "LineWidth";
    LineWidth.propertyValue = 10;
    LineWidth.updateType = Update|OrdinaryAttributes;
    LineWidth.propertyType = QrealPropertyType;
    LineWidth.updatePropertyFun = (GY_PropertyInfo::UpdatePropertyFun)&GY_AttributesGroup::updateLineWidth;
    m_PropertyInfoMap.insert("LineWidth",LineWidth);
    m_PropertyInfoMap[LineWidth.propertyName].setConnect();

}

bool GY_AttributesGroup::updatePosition(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>())
    {
        return false;
    }
    //setpos设置为父级坐标
    QPointF point = value.toPointF();
    if(this->parentItem()) {
        point = this->mapToParent(this->mapFromScene(value.toPointF()));
    }
    this->setPos(point);
    m_PropertyInfoMap[name].propertyValue=this->mapFromScene(value.toPointF());
    return true;
}

bool GY_AttributesGroup::updateFillAttributes(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updateFillStyle(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updateFillColor(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QColor>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updateFillGradient(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QVector<qreal>>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updatePattern(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QString>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updateFillOpacity(const QString &name, const QVariant &value)
{
    if(!value.canConvert<qreal>())
    {
        return false;
    }
    qreal dvalue = value.toReal();
    if(dvalue > 1 && dvalue < 0)
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updatePenAttributes(const QString &name, const QVariant &value)
{
    if(!value.canConvert<bool>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updatePenColor(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QColor>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updateLineStyle(const QString &name, const QVariant &value)
{
    if(!value.canConvert<LineStyle>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updatePenOpacity(const QString &name, const QVariant &value)
{
    if(!value.canConvert<qreal>())
    {
        return false;
    }
    qreal dvalue = value.toReal();
    if(dvalue > 1 && dvalue < 0)
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::updateLineWidth(const QString &name, const QVariant &value)
{
    if(!value.canConvert<qreal>())
    {
        return false;
    }
    m_PropertyInfoMap[name].propertyValue=value;
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::addItem(GY_Object *pItem)
{
    if(pItem->inherits("GY_BasicsGraphicsObject"))
    {
        this->addToGroup((GY_BasicsGraphicsObject*)pItem);
    }
    else if(pItem->inherits("GY_ContainerTransform"))
    {
        this->addToGroup((GY_ContainerTransform*)pItem);
    }
    else
    {
        return false;
    }
    m_ChildrensMap.insert(pItem->getGuid(),pItem);
    m_OrderChildrens.append(pItem);
    setContainerEditPointF();
    //设置父级
    pItem->setParent(this);
    updateSubclassBrushes(this);
    return true;
}

bool GY_AttributesGroup::removItem(const QString &guid)
{
    if(!m_ChildrensMap.contains(guid))
    {
        return false;
    }
    m_ChildrensMap.remove(guid);
    return true;
}

bool GY_AttributesGroup::removItem(const GY_Object *pItem)
{
    if(pItem->inherits("GY_BasicsGraphicsObject"))
    {
        this->removeFromGroup((GY_BasicsGraphicsObject*)pItem);
    }
    else if(pItem->inherits("GY_ContainerTransform"))
    {
        this->removeFromGroup((GY_ContainerTransform*)pItem);
    }
    else
    {
        return false;
    }
    m_OrderChildrens.removeOne((GY_Object *)pItem);
    //设置父级为空
    const_cast<GY_Object *>(pItem)->setParent(nullptr);
    updateSubclassBrushes(this);
    return  removItem(pItem->getGuid());
}

void GY_AttributesGroup::updateSubclassBrushes(GY_AttributesGroup *obj)
{
    QMap<QString,GY_Object*> ChildrensMap = obj->getChildrensMap();
    QMap<QString,GY_Object*>::Iterator iter = ChildrensMap.begin();
    while (iter != ChildrensMap.end()) {
        if(iter.value()->getUserData(GY_ENUM::ObjectType) == 0) {
            ((GY_BasicsGraphicsObject*)iter.value())->updataPen();
            ((GY_BasicsGraphicsObject*)iter.value())->updataBrush();

        }else if(iter.value()->getPropertyMap().contains("LineWidth")){
            updateSubclassBrushes((GY_AttributesGroup *)iter.value());
        }
        ++iter;
    }
}



